﻿using System;
using System.Collections.Generic;
using AudioStudio;
using FlowCanvas.Nodes;
using FluffyUnderware.Curvy.Controllers;
using NpcFramework;
using UnityEngine;

namespace Yoozoo.Gameplay.Liberty.AI
{

    public enum SpeedStatus
    {
        None = 0,
        Acc = 1,
        Dec = 2,
    }
    
    [RequireComponent(typeof(Collider))]
    [RequireComponent(typeof(SplineController))]
    public class LibertyCarSeeker : MonoBehaviour,ICarTriggerListener
    {
        [SerializeField]
        private SplineController _splineController;
        public SplineController SplineController => _splineController;
        
        public SpeedStatus speedStatus = SpeedStatus.None;
        
        public float maxSpeed = 20f;

        [Header("当前速度")]
        public float speed;
        
        [Header("加速度")]
        public float acceleration = 6f;
        [Header("刹车速度")]
        public float deceleration = 10f;

        [SerializeField]
        private TrafficCarTrigger _carTrigger;

        [SerializeField] 
        private PhysicsCasterCollection _frontCasterCollection;
        public PhysicsCasterCollection FrontCasterCollection => _frontCasterCollection;
        private List<RaycastHit> _frontCastHits;

        [SerializeField]
        private Collider _collider;
        public Collider Collider
        {
            get
            {
                if (!_collider) _collider = GetComponent<Collider>();
                return _collider;
            }
        }
        
        [SerializeField]
        private bool inRadar = false;

        public float radarAngle = 30;
        public float radarLength = 6;

        private bool isMoving;
        public bool isBarged;

        private AudioSource audioSource;
        public Rigidbody _rigidbody;
        
        private void Awake()
        {
            if (!_splineController)
            {
                _splineController = GetComponent<SplineController>();
            }
            
            if (_splineController)
            {
                _splineController.UsePhysicController = false;
                _splineController.Speed = maxSpeed;
                speed = maxSpeed;
                AudioManager.PlaySound("am_street_car_driveloop", gameObject);
            }
            _frontCastHits = new List<RaycastHit>(10);

            audioSource = gameObject.AddComponent<AudioSource>();
            _rigidbody = gameObject.GetComponent<Rigidbody>();
            _rigidbody.isKinematic = true;
            _rigidbody.useGravity = false;
        }

        public void Dispose()
        {

        }

        private void OnDisable()
        {
            AudioManager.StopSound("am_street_car_driveloop", gameObject);
        }

        public void OnPlayerRadarUpdate()
        {
            Vector3 playerPos = LibertyAIUtils.PlayerController.playerModel.position;

            float angle = Vector3.Angle(playerPos - transform.position, transform.forward);
            float distance = Vector3.Distance(playerPos, transform.position);

            if (angle <= radarAngle && distance <= radarLength)
            {
                inRadar = true;
            }
            else
            {
                inRadar = false;
            }

        }

        public void OnRemoveFromPlayerRadar()
        {
            inRadar = false;
        }
        
        private void Update()
        {
            if (speedStatus == SpeedStatus.None)
            {
                if (Mathf.Abs(maxSpeed - speed) > 0.001f)
                {
                    speed = maxSpeed;
                }
            }
        }

        private float _rayCastTime = 1000;
        private float _bargeTime = 0;
        
        private void FixedUpdate()
        {
            if (isBarged)
            {
                //_frontCasterCollection.Cast();
                _frontCasterCollection.GetHitInfo(ref _frontCastHits);
            }
            if (_frontCastHits.Count > 0)
            {
                // foreach (var hit in _frontCastHits)
                // {
                //     if (hit.collider.name.Contains("Car_"))
                //     {
                //         LibertyAIUtils.AIManager.CarBirthManager.col2CarSeekerMap.TryGetValue(hit.collider, out var carSeeker);
                //         if (carSeeker != null)
                //         {
                //             carSeeker.SetCarAcc();
                //             break;
                //         }
                //     }
                // }
            }
            
            if (_rayCastTime > 0.15f)
            {
                _rayCastTime = 0;
                _frontCastHits.Clear();
                if (_frontCasterCollection)
                {
                    _frontCasterCollection.Cast();
                    _frontCasterCollection.GetHitInfo(ref _frontCastHits);
                }
            }
            else
            {
                _rayCastTime += Time.fixedDeltaTime;
            }
            
            if (_frontCastHits.Count > 0)
            {
                speedStatus = SpeedStatus.Dec;
            }
            else
            {
                if (speedStatus == SpeedStatus.Dec)
                {
                    if (_carTrigger != null && _carTrigger.lightState == TrafficLightState.Green)
                    {
                        speedStatus = SpeedStatus.Acc;
                        isMoving = false;
                    }
                    else if (_carTrigger == null)
                    {
                        speedStatus = SpeedStatus.Acc;
                        isMoving = false;
                    }
                }
            }
            
            
            if (speedStatus == SpeedStatus.Acc)
            {
                speed = Mathf.Min(maxSpeed, speed + acceleration * Time.fixedDeltaTime);
                if (!isMoving)
                {
                    isMoving = true;
                    AudioManager.StopSound("am_street_car_stop", gameObject);
                    AudioManager.PlaySound("am_street_car_driveloop", gameObject);
                }
            }
            else if (speedStatus == SpeedStatus.Dec)
            {
                speed = Mathf.Max(0, speed - deceleration * Time.fixedDeltaTime);
                if (isMoving)
                {
                    isMoving = false;
                    AudioManager.StopSound("am_street_car_driveloop", gameObject);
                    AudioManager.PlaySound("am_street_car_stop", gameObject);
                }
            }

            _splineController.Speed = speed;
        }

        private void OnTriggerEnter(Collider other)
        {
            if (TrafficCarTrigger.CarTriggerMap.TryGetValue(other,out var carTrigger))
            {
                if (!carTrigger.greenState)
                {
                    // 等待红绿灯，减速
                    speedStatus = SpeedStatus.Dec;
                }
                carTrigger.AddTriggerListener(this);
                this._carTrigger = carTrigger;
            }
        }

        private void OnTriggerExit(Collider other)
        {
            if (TrafficCarTrigger.CarTriggerMap.TryGetValue(other,out var carTrigger))
            {
                carTrigger.RemoveTriggerListener(this);
                if (speedStatus == SpeedStatus.Dec)
                {
                    speedStatus = SpeedStatus.Acc;
                }

                this._carTrigger = null;
            }
        }

        public void OnChangeState(TrafficLightState lightState)
        {
            if (lightState == TrafficLightState.Green)
            {
                speedStatus = SpeedStatus.Acc;
            }
        }
        
        public void SetCarAcc()
        {
            speedStatus = SpeedStatus.Acc;
        }
    }
}